package com.sunrise.configuracoes.repositorio;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.sunrise.configuracoes.repositorio.iface.FilialDao;
import com.sunrise.generico.acesso.DaoService;
import com.sunrise.generico.entidade.Filial;
import com.sunrise.generico.entidade.Usuario;
import com.sunrise.generico.visao.Filtro;

@Repository
public class FilialDaoImpl extends DaoService<Filial> implements FilialDao {

	public List<Filial> listarOrdenado() {
		List<Filial> list = listar(Filial.class);
		Collections.sort(list, new Comparator<Filial>() {

			@Override
			public int compare(Filial o1, Filial o2) {
				return o1.getNome().compareTo(o2.getNome());
			}
		});
		return list;
	}

	public List<Filial> search(Filial ex) {
		List<Filial> list =  searchByExample(Filial.class, ex);
		Collections.sort(list, new Comparator<Filial>() {

			@Override
			public int compare(Filial o1, Filial o2) {
				return o1.getNome().compareTo(o2.getNome());
			}
		});
		return list;
	}

	public Filial getById(Long id) {
		return getById(id, Filial.class);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Filial> listarPorNome(String nome) {
		Criteria crit = getSession().createCriteria(Filial.class);
		crit.add(Restrictions.ilike("nome", nome, MatchMode.ANYWHERE));
		return crit.list();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Collection<Filial> buscarPorFiltros(Filtro filial) {
		Criteria crit = getSession().createCriteria(Filial.class);
		if (filial.getNome() != null && !filial.getNome().isEmpty()) {
			crit.add(Restrictions.ilike("nome", filial.getNome(), MatchMode.ANYWHERE));
		}
		
		if (filial.getResponsavel() != null && !filial.getResponsavel().isEmpty()) {
			crit.createAlias("responsavel", "resp");
			crit.add(Restrictions.ilike("resp.nome", filial.getResponsavel(), MatchMode.ANYWHERE));
		}
		
		if (filial.getCidade() != null && !filial.getCidade().isEmpty()) {
			crit.createAlias("endereco", "end");
			crit.createAlias("end.cidade", "cid");
			crit.add(Restrictions.ilike("nome", filial.getCidade(), MatchMode.ANYWHERE));
		}

		if (filial.getAtivo() != null) {
			crit.add(Restrictions.eq("ativo", filial.getAtivo().getCodigo()));
		}
		
		crit.addOrder(Order.asc("nome"));
		return crit.list();
	}
	
	@Override
	public Filial buscarPorNome(String nome) {
		Criteria crit = getSession().createCriteria(Filial.class);
		crit.add(Restrictions.eq("nome", nome).ignoreCase());
		return (Filial) crit.uniqueResult();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<Filial> listarAtivoOrdenado() {
		Criteria crit = getSession().createCriteria(Filial.class);
		crit.add(Restrictions.eq("ativo", true));
		crit.addOrder(Order.asc("quantidade"));
		return crit.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<Filial> listarPorUsuario(Usuario usuario) {
		Criteria crit = getSession().createCriteria(Filial.class);
		crit.createAlias("usuarios", "usuario");
		crit.add(Restrictions.eq("usuario.id", usuario.getId()));
		crit.add(Restrictions.eq("ativo", Boolean.TRUE));
		return crit.list();
	}

	@Override
	public Filial buscarPorCNPJ(String cnpj) {
		Criteria crit = getSession().createCriteria(Filial.class);
		crit.add(Restrictions.eq("cnpj",cnpj));
		return (Filial) crit.uniqueResult();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<Filial> listarPorNomeUsuario(String nome, Usuario usuario) {
		Criteria crit = getSession().createCriteria(Filial.class);
		if (nome != null && !nome.isEmpty()) {
			crit.add(Restrictions.ilike("nome", nome, MatchMode.ANYWHERE));
		}
		
		crit.createAlias("usuarios", "usuario");
		crit.add(Restrictions.eq("usuario.id", usuario.getId()));
		crit.add(Restrictions.eq("ativo", Boolean.TRUE));
		return crit.list();
	}

}
